using System;
using System.IO;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

using MSHelpLib;
using MSHelpLib.BaseCode;

namespace MSHelpReader
{
	/// <summary>
	/// Summary description for frmExplorer.
	/// </summary>
	public class frmExplorer : System.Windows.Forms.Form
	{
		private System.Windows.Forms.TreeView treeView1;
		private System.Windows.Forms.Splitter splitter1;
		private System.Windows.Forms.Panel panel1;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Button btnExtract;
		private System.Windows.Forms.Label lbFilename;
		private System.Windows.Forms.Label lbSize;
		private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		private MSHelpLib.IHelpSystem ExploreFile=null;
		private System.Windows.Forms.ProgressBar progressBar1;
		private Hashtable buildinfo=null;

		private string m_FileName="";
        /// <summary>
        /// Initializes a new instance of the <see cref="frmExplorer"/> class.
        /// </summary>
        /// <param name="FileName">Name of the file.</param>
		public frmExplorer(string FileName)
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();
			m_FileName=FileName;
		}
		
		private MSHelpLib.PAFEnum ListAllFiles(IFileInfo fileInfo)
		{
			// Add item to tree
			progressBar1.PerformStep();

			// Split filename into parts, and add each part, first checking to see if that part exists.
			string filename=fileInfo.FileName;
			filename=filename.Replace("\\","/");
			if (filename.StartsWith("/"))
				filename=filename.Substring(1);

			if (filename.Length==0)
				return MSHelpLib.PAFEnum.Continue;

			string [] parts=filename.Trim().Split('/');
			TreeNode item=null;
			TreeNode parent=null;
			foreach(string p in parts)
			{
				if (p=="")
					continue;
				item=new TreeNode(p);
				item.Tag=fileInfo;

				if (buildinfo.ContainsKey(p))
				{
					parent=(TreeNode)buildinfo[p];
				}
				else
				{
					// Does not exist					
					buildinfo.Add(p,item);

					if (parent==null)
					{
						treeView1.Nodes.Add(item);						
					}
					else
						parent.Nodes.Add(item);

					parent=item;
				}
			}			

			return MSHelpLib.PAFEnum.Continue;
		}		

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.treeView1 = new System.Windows.Forms.TreeView();
			this.splitter1 = new System.Windows.Forms.Splitter();
			this.panel1 = new System.Windows.Forms.Panel();
			this.btnExtract = new System.Windows.Forms.Button();
			this.label1 = new System.Windows.Forms.Label();
			this.lbFilename = new System.Windows.Forms.Label();
			this.label3 = new System.Windows.Forms.Label();
			this.lbSize = new System.Windows.Forms.Label();
			this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog();
			this.progressBar1 = new System.Windows.Forms.ProgressBar();
			this.panel1.SuspendLayout();
			this.SuspendLayout();
			// 
			// treeView1
			// 
			this.treeView1.Dock = System.Windows.Forms.DockStyle.Left;
			this.treeView1.ImageIndex = -1;
			this.treeView1.Location = new System.Drawing.Point(0, 0);
			this.treeView1.Name = "treeView1";
			this.treeView1.SelectedImageIndex = -1;
			this.treeView1.Size = new System.Drawing.Size(121, 373);
			this.treeView1.TabIndex = 0;
			this.treeView1.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView1_AfterSelect);
			// 
			// splitter1
			// 
			this.splitter1.Location = new System.Drawing.Point(121, 0);
			this.splitter1.Name = "splitter1";
			this.splitter1.Size = new System.Drawing.Size(3, 373);
			this.splitter1.TabIndex = 1;
			this.splitter1.TabStop = false;
			// 
			// panel1
			// 
			this.panel1.Controls.Add(this.progressBar1);
			this.panel1.Controls.Add(this.lbSize);
			this.panel1.Controls.Add(this.label3);
			this.panel1.Controls.Add(this.lbFilename);
			this.panel1.Controls.Add(this.label1);
			this.panel1.Controls.Add(this.btnExtract);
			this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panel1.Location = new System.Drawing.Point(124, 0);
			this.panel1.Name = "panel1";
			this.panel1.Size = new System.Drawing.Size(492, 373);
			this.panel1.TabIndex = 2;
			// 
			// btnExtract
			// 
			this.btnExtract.Location = new System.Drawing.Point(16, 8);
			this.btnExtract.Name = "btnExtract";
			this.btnExtract.TabIndex = 0;
			this.btnExtract.Text = "Extract";
			this.btnExtract.Click += new System.EventHandler(this.btnExtract_Click);
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(16, 40);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(56, 16);
			this.label1.TabIndex = 1;
			this.label1.Text = "Filename";
			// 
			// lbFilename
			// 
			this.lbFilename.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
				| System.Windows.Forms.AnchorStyles.Right)));
			this.lbFilename.Location = new System.Drawing.Point(80, 40);
			this.lbFilename.Name = "lbFilename";
			this.lbFilename.Size = new System.Drawing.Size(408, 16);
			this.lbFilename.TabIndex = 2;
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(16, 64);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(48, 16);
			this.label3.TabIndex = 3;
			this.label3.Text = "Size";
			// 
			// lbSize
			// 
			this.lbSize.Location = new System.Drawing.Point(80, 64);
			this.lbSize.Name = "lbSize";
			this.lbSize.Size = new System.Drawing.Size(100, 16);
			this.lbSize.TabIndex = 4;
			// 
			// folderBrowserDialog1
			// 
			this.folderBrowserDialog1.Description = "Select Save Location for file.";
			// 
			// progressBar1
			// 
			this.progressBar1.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.progressBar1.Location = new System.Drawing.Point(0, 357);
			this.progressBar1.Name = "progressBar1";
			this.progressBar1.Size = new System.Drawing.Size(492, 16);
			this.progressBar1.TabIndex = 5;
			// 
			// frmExplorer
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(616, 373);
			this.Controls.Add(this.panel1);
			this.Controls.Add(this.splitter1);
			this.Controls.Add(this.treeView1);
			this.Name = "frmExplorer";
			this.Text = "frmExplorer";
			this.Load += new System.EventHandler(this.frmExplorer_Load);
			this.panel1.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion


		private void btnExtract_Click(object sender, System.EventArgs e)
		{
			IFileInfo fi=(IFileInfo)treeView1.SelectedNode.Tag;
			if (fi==null)
				return;
			
			if (fi.Length==0)
			{
				MessageBox.Show("Selected Item has zero length");
				return;
			}

			if (folderBrowserDialog1.ShowDialog()!=DialogResult.OK)
				return;

			MemoryStream memStream=null;
			try
			{
				memStream=this.ExploreFile.Extract(fi);
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
				return;
			}
			if (memStream==null)
			{
				MessageBox.Show("Failed to extract file");
				return;
			}
			if (memStream.Length==0)
			{
				MessageBox.Show("Extracted file has length of zero.");
				return;
			}

			FileStream fs=new FileStream(this.folderBrowserDialog1.SelectedPath+@"\"+Path.GetFileName(fi.FileName),FileMode.Create);
			byte []buf=memStream.ToArray();
			fs.Write(buf,(int)0,(int)memStream.Length);
			fs.Close();
			memStream.Close();			
		}

		private void treeView1_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			IFileInfo fi=(IFileInfo)treeView1.SelectedNode.Tag;
			if (fi==null)
			{
				lbFilename.Text="";
				lbSize.Text="";
				return;
			}
			lbFilename.Text=fi.FileName;
			string suffix="b";
			ulong len=fi.Length;
			if (len>1024)
			{
				len/=1024;
				suffix="Kb";
			}
			if (len>1024)
			{
				len/=1024;
				suffix="Mb";
			}
			if (len>1024)
			{
				len/=1024;
				suffix="Gb";
			}
			lbSize.Text=len.ToString()+suffix;
		}

		private void frmExplorer_Load(object sender, System.EventArgs e)
		{
			this.Show();
			this.Refresh();
			buildinfo=new Hashtable();

			FileInfo fi=new FileInfo(m_FileName);
			ExploreFile=new MSHelpLib.HelpSystem();								
			ExploreFile.Open(m_FileName,(int)LoadFlags.LoadOnlySystemData);
			progressBar1.Minimum=0;
			progressBar1.Maximum=ExploreFile.NumberOfFiles;
			progressBar1.Value=0;
			progressBar1.Step=1;
			ExploreFile.ProcessAllFiles(new MSHelpLib.ProcessAllFilesDelegate(ListAllFiles));						
			progressBar1.Value=0;
		}
	}
}
